﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using BoardPACDSDAO.Entity;
using BoardPACUtil.Util;
using BoardPACDSBO.Admin;
using BoardPACDSBO.DownloadApp;

namespace BoardPACDSDAO.DownloadApp
{
    public class DownloadAppDAO
    {
        public DownloadAppModel UpdateDB(string iPaVersion, string dbVersion, int userId)
        {
            DownloadAppModel downloadModel = new DownloadAppModel();
            try
            {
                using (BoardAppProductEntities entities = DataObjectFactory.CreateContext())
                {
                    if (iPaVersion == null)
                    {
                        throw new GenServiceException("err_881");
                    }

                    if (dbVersion == null)
                    {
                        throw new GenServiceException("err_883");
                    }

                    downloadModel.iPaVersion = iPaVersion;
                    downloadModel.dbVersion = dbVersion;

                    List<iPadDB> iPadDBScripts = new List<iPadDB>();
                    List<iPadDB> iPadDBAllScripts = (from i in entities.iPadDBs
                                                     select i).ToList();

                    List<string> Versions = (from i in iPadDBAllScripts
                                             select i.Version).Distinct().ToList();

                    int minScriptNumber = 0;
                    if (!Versions.Exists(i => i == dbVersion))
                    {
                        dbVersion = GetMinExistingVersion(dbVersion, Versions);
                    }

                    if (!string.IsNullOrWhiteSpace(dbVersion))
                    {
                        minScriptNumber = (from x in iPadDBAllScripts
                                           where x.Version.Equals(dbVersion)
                                           select x.ScriptOrder).Min();

                        int maxScriptNumber = 0;
                        if (!Versions.Exists(i => i == iPaVersion))
                        {
                            iPaVersion = GetMaxExistingVersion(iPaVersion, Versions);
                        }
                        if (!string.IsNullOrWhiteSpace(iPaVersion))
                        {
                            maxScriptNumber = (from x in iPadDBAllScripts
                                               where x.Version.Equals(iPaVersion)
                                               select x.ScriptOrder).Max();

                            if (maxScriptNumber >= minScriptNumber)
                            {
                                iPadDBScripts = (from i in entities.iPadDBs
                                                 where i.ScriptOrder <= maxScriptNumber && i.ScriptOrder >= minScriptNumber
                                                 orderby i.ScriptOrder
                                                 select i).ToList();

                                downloadModel.iPadDBScripts = ConvertEntityToModel(iPadDBScripts);
                            }
                            else
                            {
                                downloadModel.MessageCode = 1;
                                //ViewData["Message"] = Resources.info_ipaVersionDBVersionIssue;
                            }
                        }
                        else
                        {
                            downloadModel.MessageCode = 2;
                            //ViewData["Message"] = Resources.info_ipaVersionOutOfDateMsg;
                        }
                    }
                    else
                    {
                        downloadModel.MessageCode = 3;
                        //ViewData["Message"] = Resources.info_dbVersionUptodateMsg;
                    }

                    int customUserId = userId;
                    User user = (from u in entities.Users
                                 where u.CustomUserId == customUserId
                                 select u).FirstOrDefault();

                    downloadModel.Username = user.UserName;
                    //ViewData["UserName"] = user.UserName;
                }
                return downloadModel;
            }
            catch (Exception)
            {
                throw;
            }
        }

        private List<iPadDBModel> ConvertEntityToModel(List<iPadDB> iPadDBScripts)
        {
            List<iPadDBModel> list = new List<iPadDBModel>();
            foreach (iPadDB item in iPadDBScripts)
            {
                iPadDBModel model = new iPadDBModel();
                //model.EntityKey = item.EntityKey;
                //model.EntityState = item.EntityState;
                model.Id = item.Id;
                model.Script = item.Script;
                model.ScriptOrder = item.ScriptOrder;
                model.Version = item.Version;
                
                list.Add(model);
            }
            return list;
        }

        private string GetMinExistingVersion(String dbVersion, List<string> Versions)
        {
            String[] VersionToCompare = dbVersion.Split('.');
            int[] clientDBVersionToCompare = new int[VersionToCompare.Length];
            int index = 0;
            foreach (var item in VersionToCompare)
            {
                clientDBVersionToCompare[index] = int.Parse(item);
                index++;
            }

            string minVersion = string.Empty;
            int[] minVersionIntArray = new int[VersionToCompare.Length];
            int[] minClientVersionToCompare = new int[VersionToCompare.Length];

            //traversing all the distinct versions in the table to find the 'CEIL' of dbVersion
            foreach (var itemVersion in Versions)
            {
                String[] VersionFromList = itemVersion.Split('.');
                index = 0;
                bool greaterThanDBVersion = false;
                foreach (var item in VersionFromList)
                {
                    minClientVersionToCompare[index] = int.Parse(item);
                    if (clientDBVersionToCompare[index] < minClientVersionToCompare[index])
                    {
                        greaterThanDBVersion = true;
                    }
                    else if (!greaterThanDBVersion && clientDBVersionToCompare[index] > minClientVersionToCompare[index])
                    {
                        break;
                    }
                    index++;
                }

                //getting the CEIL of Versions > DBVersion
                if (greaterThanDBVersion)
                {
                    if (!String.IsNullOrWhiteSpace(minVersion))
                    {
                        for (int i = 0; i < VersionToCompare.Length; i++)
                        {
                            if (minVersionIntArray[i] < minClientVersionToCompare[i])
                            {
                                break;
                            }
                            else if (minVersionIntArray[i] > minClientVersionToCompare[i])
                            {
                                minVersion = itemVersion;
                                for (int j = 0; j < VersionToCompare.Length; j++)
                                {
                                    minVersionIntArray[j] = minClientVersionToCompare[j];
                                }
                                break;
                            }
                        }
                    }
                    else
                    {
                        minVersion = itemVersion;
                        for (int j = 0; j < VersionToCompare.Length; j++)
                        {
                            minVersionIntArray[j] = minClientVersionToCompare[j];
                        }
                    }
                }
            }
            return minVersion;
        }

        private string GetMaxExistingVersion(String iPaVersion, List<string> Versions)
        {
            String[] VersionToCompare = iPaVersion.Split('.');
            int[] clientIPAVersionToCompare = new int[VersionToCompare.Length];
            int index = 0;

            foreach (var item in VersionToCompare)
            {
                clientIPAVersionToCompare[index] = int.Parse(item);
                index++;
            }

            string maxVersion = string.Empty;
            int[] maxVersionIntArray = new int[VersionToCompare.Length];
            int[] maxClientVersionToCompare = new int[VersionToCompare.Length];

            //traversing all the distinct versions in the table to find the 'FLOOR' of iPaVersion
            foreach (var itemVersion in Versions)
            {
                String[] VersionFromList = itemVersion.Split('.');
                index = 0;
                bool lessThanIPAVersion = false;
                foreach (var item in VersionFromList)
                {
                    maxClientVersionToCompare[index] = int.Parse(item);
                    if (clientIPAVersionToCompare[index] > maxClientVersionToCompare[index])
                    {
                        lessThanIPAVersion = true;
                    }
                    else if (!lessThanIPAVersion && clientIPAVersionToCompare[index] < maxClientVersionToCompare[index])
                    {
                        break;
                    }
                    index++;
                }

                if (lessThanIPAVersion) //getting the FLOOR of Versions < IPAVersion
                {
                    if (!String.IsNullOrWhiteSpace(maxVersion))
                    {
                        for (int i = 0; i < VersionToCompare.Length; i++)
                        {
                            if (maxVersionIntArray[i] > maxClientVersionToCompare[i])
                            {
                                break;
                            }
                            else if (maxVersionIntArray[i] < maxClientVersionToCompare[i])
                            {
                                maxVersion = itemVersion;
                                for (int j = 0; j < VersionToCompare.Length; j++)
                                {
                                    maxVersionIntArray[j] = maxClientVersionToCompare[j];
                                }
                                break;
                            }
                        }
                    }
                    else
                    {
                        maxVersion = itemVersion;
                        for (int j = 0; j < VersionToCompare.Length; j++)
                        {
                            maxVersionIntArray[j] = maxClientVersionToCompare[j];
                        }
                    }
                }
            }
            return maxVersion;
        }
    }
}
